﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lumo.display.object2D;
using Microsoft.Xna.Framework;

namespace lumo.display.animation2D
{
    /// <summary>
    /// An angle animation for an object using the shortest path between those.
    /// </summary>
    public class ShortAngleAnimation2D : GenericAnimation2D<IRotationable2D>
    {
        // Private variables
        private float? From = null;
        private float To;
        private Counter RadianCounter = new Counter();

        /// <summary>
        /// Constructor
        /// </summary>
        public ShortAngleAnimation2D(float To, float Time, Smooth Smoothness = Smooth.None, Loop LoopMode = Loop.None, IRotationable2D CurrentObject = null)
            : base(Time, Smoothness, LoopMode, CurrentObject)
        {
            this.To = To;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public ShortAngleAnimation2D(float? From, float To, float Time, Smooth Smoothness = Smooth.None, Loop LoopMode = Loop.None, IRotationable2D CurrentObject = null)
            : base(Time, Smoothness, LoopMode, CurrentObject)
        {
            this.From = From;
            this.To = To;
        }

        /// <summary>
        /// Check if finished
        /// </summary>
        public override bool Finished { get { return (RadianCounter.Finished); } }

        /// <summary>
        /// Setup the values
        /// </summary>
        internal override void SetupValues()
        {
            float f = (this.From.HasValue ? this.From.Value : this.CurrentObject.Radians);
            float t = this.To;
            while (f >= MathHelper.TwoPi)  f -= MathHelper.TwoPi;
            while (f <= -MathHelper.TwoPi) f += MathHelper.TwoPi;
            while (t >= MathHelper.TwoPi)  t -= MathHelper.TwoPi;
            while (t <= -MathHelper.TwoPi) t += MathHelper.TwoPi;

            if (Math.Abs(t - f) >= Math.PI)
            {
                if ((t - f) < 0)
                    t += MathHelper.TwoPi;
                else
                    t -= MathHelper.TwoPi;
            }

            RadianCounter.Reset(f, t, this.Time, this.Smoothness, this.LoopMode);
        }

        /// <summary>
        /// Update the values.
        /// </summary>
        /// <param name="Game">The game class</param>
        internal override void UpdateValues(LumoComponent Game)
        {
            RadianCounter.Update(Game);
            this.CurrentObject.Radians = RadianCounter.Value;
        }
    }
}
